﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using IISDeploy.Data.Interceptor;
using IISDeploy.Configuration;
using NHibernate.Engine;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Mapping;

namespace IISDeploy.Data.Helper
{
    public static class NHibernateHelper
    {
        #region Fields

        private static ISessionFactory m_factory;
        private static ISession session;
        private static int totalSessions = 0;

        #endregion


        #region Methods
        private static void BuildFactory()
        {
            if (m_factory == null)
            {
                try
                {
                    NHibernate.Cfg.Environment.BytecodeProvider = new UnityBytecodeProvider(DependencyContainer.Instance.Container);
                    NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
                    cfg.Configure();
                    cfg.Interceptor = new UnityInterceptor(DependencyContainer.Instance.Container);
                    m_factory = cfg.BuildSessionFactory();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        public static ISession OpenSession()
        {
            BuildFactory();
            if (session == null)
                session = m_factory.OpenSession();

            totalSessions++;

            return session;
        }

        public static IList<T> FindAll<T>()
        {
            ISession session = OpenSession();
            try
            {
                IList<T> list = session.CreateCriteria(typeof(T)).List<T>();
                return list;
            }
            finally
            {
                Close();
            }
        }

        public static T FindByPrimaryKey<T>(object id)
        {
            ISession session = OpenSession();
            T obj;
            try
            {
                obj = session.Load<T>(id);
            }
            catch
            {
                obj = default(T);
            }
            finally
            {
                Close();
            }
            return obj;
        }

        public static void Save(object obj)
        {
            ISession session = OpenSession();
            session.SaveOrUpdate(obj);
            session.Flush();
            Close();
        }

        public static void Delete(object obj)
        {
            ISession session = OpenSession();
            session.Delete(obj);
            session.Flush();
            Close();
        }

        public static void Close()
        {
            if (totalSessions.Equals(1))
            {
                session.Close();
                session.Dispose();
                session = null;
                totalSessions = 0;
            }
            else
                totalSessions--;

        }

        #endregion
    }
}
